% TODO proof-reading
\subsubsection{Функции с переменным кол-вом аргументов (variadic)}


Функции с переменным кол-вом аргументов (variadic) на самом деле используют массивы:

\begin{lstlisting}[style=customjava]
	public static void f(int... values)
	{
		for (int i=0; i<values.length; i++)
			System.out.println(values[i]);
	}

	public static void main(String[] args) 
	{
		f (1,2,3,4,5);
	}
\end{lstlisting}

\begin{lstlisting}
  public static void f(int...);
    flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
    Code:
      stack=3, locals=2, args_size=1
         0: iconst_0      
         1: istore_1      
         2: iload_1       
         3: aload_0       
         4: arraylength   
         5: if_icmpge     23
         8: getstatic     #2       // Field java/lang/System.out:Ljava/io/PrintStream;
        11: aload_0       
        12: iload_1       
        13: iaload        
        14: invokevirtual #3       // Method java/io/PrintStream.println:(I)V
        17: iinc          1, 1
        20: goto          2
        23: return        
\end{lstlisting}


По смещению 3, \ttf просто берет массив переменных используя \TT{aload\_0}.

Затем берет размер массива, итд.

\begin{lstlisting}
  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=1, args_size=1
         0: iconst_5      
         1: newarray       int
         3: dup           
         4: iconst_0      
         5: iconst_1      
         6: iastore       
         7: dup           
         8: iconst_1      
         9: iconst_2      
        10: iastore       
        11: dup           
        12: iconst_2      
        13: iconst_3      
        14: iastore       
        15: dup           
        16: iconst_3      
        17: iconst_4      
        18: iastore       
        19: dup           
        20: iconst_4      
        21: iconst_5      
        22: iastore       
        23: invokestatic  #4       // Method f:([I)V
        26: return        
\end{lstlisting}


Массив конструируется в \main используя инструкцию \TT{newarray}, 
затем он заполняется, и вызывается \ttf.


Кстати, объект массива не уничтожается в конце \main.
\myindex{Сборщик мусора}

В Java вообще нет деструкторов, потому что в JVM есть сборщик мусора (garbage collector),
делающий это автоматически, когда считает нужным.


Как насчет метода \TT{format()}?

Он берет на вход два аргумента: строку и массив объектов:

\begin{lstlisting}
	public PrintStream format(String format, Object... args)
\end{lstlisting}
( \url{http://docs.oracle.com/javase/tutorial/java/data/numberformat.html} )

Посмотрим:

\begin{lstlisting}[style=customjava]
	public static void main(String[] args)
	{
		int i=123;
		double d=123.456;
		System.out.format("int: %d double: %f.%n", i, d);
	}
\end{lstlisting}

\begin{lstlisting}
  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=7, locals=4, args_size=1
         0: bipush        123
         2: istore_1      
         3: ldc2_w        #2         // double 123.456d
         6: dstore_2      
         7: getstatic     #4         // Field java/lang/System.out:Ljava/io/PrintStream;
        10: ldc           #5         // String int: %d double: %f.%n
        12: iconst_2      
        13: anewarray     #6         // class java/lang/Object
        16: dup           
        17: iconst_0      
        18: iload_1       
        19: invokestatic  #7         // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        22: aastore       
        23: dup           
        24: iconst_1      
        25: dload_2       
        26: invokestatic  #8         // Method java/lang/Double.valueOf:(D)Ljava/lang/Double;
        29: aastore       
        30: invokevirtual #9         // Method java/io/PrintStream.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/io/PrintStream;
        33: pop           
        34: return        
\end{lstlisting}


Так что в начале значения типов \IT{int} и \IT{double} конвертируются в объекты типов 
\TT{Integer} и \TT{Double} используя методы \TT{valueOf}.

Метод \TT{format()} требует на входе объекты типа \TT{Object}, а так как классы \TT{Integer} и
\TT{Double} наследуются от корневого класса \TT{Object}, они подходят как элементы
во входном массиве.

С другой стороны, массив всегда гомогенный, т.е. он не может содержать элементы разных типов,
что делает невозможным хранение там значений типов \IT{int} и \IT{double}.


Массив объектов \TT{Object} создается по смещению 13, 
объект \TT{Integer} добавляется в массив по смещению 22, 
объект \TT{Double} добавляется в массив по смещению 29.


Предпоследняя инструкция \TT{pop} удаляет элемент на \ac{TOS}, 
так что в момент исполнения \TT{return}, стек пуст (или сбалансирован).
